package icegps.com.pingdj.map;

import android.graphics.Canvas;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import icegps.com.pingdj.App;
import icegps.com.pingdj.bean.DeviceStatus;
import icegps.com.pingdj.bean.LocationStatus;
import icegps.com.pingdj.map.bean.MapStatus;
import icegps.com.pingdj.map.bean.MapText;
import icegps.com.pingdj.map.bean.XYCAD;
import icegps.com.pingdj.map.draw.DrawBitmap;
import icegps.com.pingdj.map.draw.DrawLine;
import icegps.com.pingdj.map.draw.DrawPoint;
import icegps.com.pingdj.map.draw.DrawText;
import icegps.com.pingdj.map.listener.OnInfoAndConfigCallback;
import icegps.com.pingdj.map.listener.OnMapEventListener;
import icegps.com.pingdj.map.listener.OnSaveBitmapListener;
import icegps.com.pingdj.map.listener.TriggerToDrawImpl;
import icegps.com.pingdj.map.thread.MapRunnable;
import icegps.com.pingdj.map.thread.ThreadPool;
import icegps.com.pingdj.map.utils.DataManager;
import icegps.com.pingdj.map.utils.TileUtils;

import static icegps.com.pingdj.constant.MapCons.mapAccuracy;


/**
 * //地图数据管理类
 * Created by 111 on 2018/2/26.
 */

public class MapManager {
    public static int workWidth;
    public static int windowWidth;
    public static int windowHeight;
    private MapView mapView;
    private DrawBitmap drawBitmap;
    private DrawPoint drawPoint;
    private MapStatus mapStatus;
    private double oldX;
    private double oldY;
    private CopyOnWriteArrayList<XYCAD> xycads = new CopyOnWriteArrayList<>();
    private final DataManager dataManager;
    private DrawLine drawLine;
    private TileUtils tileUtils;
    private DrawText drawText;
    private boolean isShow;
    private ArrayList<HashMap<String, MapText>> hashMaps;


    public MapManager(MapView mapView, long loadToken, long saveToken) {
        workWidth = Math.round(DeviceStatus.getDeviceStatus().getWorkWidth());
        if (workWidth < 1) workWidth = 1;
        this.mapView = mapView;
        hashMaps = new ArrayList<>();
        windowWidth = App.getInstance().getWindowWidth();
        windowHeight = App.getInstance().getWindowHeight();
        tileUtils = new TileUtils(loadToken, saveToken);
        dataManager = new DataManager(loadToken, saveToken, tileUtils);
        mapStatus = mapView.getMapStatus();
        drawBitmap = new DrawBitmap(mapStatus);
        drawPoint = new DrawPoint(mapStatus);
        drawLine = new DrawLine(mapStatus);
        drawText = new DrawText(mapStatus);
        mapView.addTriggerToDraw(triggerToDraw);
        mapView.addOnMapEventListener(onMapEventListener);
        for (int i = 0; i < 10; i++) {
            hashMaps.add(new HashMap<>());
        }
    }

    public void loadTile() {
        dataManager.loadTile(mapStatus);
    }

    /**
     * 刷新地图数据
     *
     * @param locationStatus
     */

    public void refreshData(LocationStatus locationStatus) {
        ThreadPool.getInstance().executeFixed(new MapRunnable() {
            @Override
            public void run() {
                super.run();
                double x = locationStatus.getX();
                double y = -locationStatus.getY();
                if (Math.sqrt((x - oldX) * (x - oldX) + (y - oldY) * (y - oldY)) > 0.1) {
                    double angle = Math.toDegrees(Math.atan2(x - oldX, y - oldY));
                    mapStatus.setAngle((float) angle);
                    oldX = x;
                    oldY = y;
                }
                xycads.clear();
                //根据铲斗宽度设置像素点覆盖区域
                for (int i = 0; i < workWidth / mapAccuracy; i++) {
                    for (int j = 0; j < workWidth / mapAccuracy; j++) {
                        xycads.add(new XYCAD(
                                        (int) locationStatus.getX() - workWidth + i,
                                        (int) locationStatus.getY() - workWidth + j,
                                        locationStatus.getColor(),
                                        locationStatus.getAltitude(),
                                        locationStatus.getDifference(),
                                        locationStatus.getStartLatitude(),
                                        locationStatus.getStartLongitude(),
                                        locationStatus.getStartAltitude()
                                )
                        );
                    }
                }
                mapStatus.setCx((float) locationStatus.getX());
                mapStatus.setCy((float) locationStatus.getY());
                mapStatus.setxTrajectory((int) locationStatus.getX());
                mapStatus.setyTrajectory((int) locationStatus.getY());

                for (XYCAD xycad : xycads) {
                    //地图测量信息    平均 当前 ......
                    dataManager.startSaveMeasureInfoData(xycad);
                    //图片处理   原始数据处理
                    dataManager.setTileData(xycad, mapStatus);
                }

                ThreadPool.getInstance().executeFixed(new Runnable() {
                    @Override
                    public void run() {

                        for (int i = 1; i <= hashMaps.size(); i++) {

                            int lenght = (workWidth * 2 * i);
                            if (i > hashMaps.size() / 2)
                                lenght += lenght / 2;
                            double drawTextX = tileUtils.getDrawTextX(locationStatus.getX(), lenght);
                            double drawTextY = tileUtils.getDrawTextY(locationStatus.getY(), lenght);
                            String textInfo = new String(drawTextX + "," + drawTextY);
                            MapText mapText = new MapText((int) drawTextX, (int) drawTextY, "" + (int) locationStatus.getDifference(), lenght);
                            hashMaps.get(hashMaps.size() - i).put(textInfo, mapText);
                        }


                    }
                });

            }

            @Override
            protected String threadName() {
                return "刷新数据线程";
            }
        });
    }


    /**
     * 设置最高最低平均高度回调
     *
     * @param onHeigthInfoCallback
     */
    public void setOnHeigthInfoCallback(OnInfoAndConfigCallback onHeigthInfoCallback) {
        dataManager.setOnHeigthInfoCallback(onHeigthInfoCallback);
    }

    /**
     * 放大
     */
    public void enlargeMap() {
        mapView.animaScale(windowWidth / 2, windowHeight / 2, 1.5f);
    }

    /**
     * 缩小
     */
    public void narrow() {
        mapView.animaScale(windowWidth / 2, windowHeight / 2, 1.0f / 1.5f);
    }

    TriggerToDrawImpl triggerToDraw = new TriggerToDrawImpl() {
        @Override
        public void trigger1(Canvas canvas) {
            super.trigger1(canvas);
            drawLine.drawLine(canvas);
        }

        @Override
        public void trigger3(Canvas canvas) {
            super.trigger3(canvas);
            drawBitmap.drawBitmap(canvas);
            drawPoint.drawPoint(canvas);
            if (isShow) {
                float multiple = mapStatus.getMultiple();

                if (multiple <= 1) {
                    drawText.drawText(canvas, hashMaps.get(0));

                } else if (multiple > 1 && multiple <= 1.4) {

                    drawText.drawText(canvas, hashMaps.get(1));

                } else if (multiple > 1.4 && multiple <= 1.8) {

                    drawText.drawText(canvas, hashMaps.get(2));

                } else if (multiple > 1.8 && multiple <= 2) {

                    drawText.drawText(canvas, hashMaps.get(3));

                } else if (multiple > 2 && multiple <= 3) {

                    drawText.drawText(canvas, hashMaps.get(4));

                } else if (multiple > 3 && multiple <= 3.5) {

                    drawText.drawText(canvas, hashMaps.get(5));

                } else if (multiple > 3.5 && multiple <= 4) {

                    drawText.drawText(canvas, hashMaps.get(6));

                } else if (multiple > 4 && multiple <= 8) {

                    drawText.drawText(canvas, hashMaps.get(7));

                } else if (multiple > 8 && multiple <= 16) {

                    drawText.drawText(canvas, hashMaps.get(8));
                } else {

                    drawText.drawText(canvas, hashMaps.get(9));
                }

            }
        }
    };


    OnMapEventListener onMapEventListener = new OnMapEventListener() {
        @Override
        public void onUpEvent() {
            dataManager.loadTile(mapStatus);
        }

        @Override
        public void onScaleEnd() {
            dataManager.loadTile(mapStatus);
        }
    };

    public void onDestroy() {

        onMapEventListener = null;
    }


    public void saveData(OnSaveBitmapListener onSaveBitmapListener, boolean isFinish) {
        ThreadPool.getInstance().executeFixed(new Runnable() {
            @Override
            public void run() {
                dataManager.saveSQData();
                dataManager.saveAllTile();
                if (onSaveBitmapListener != null) {
                    onSaveBitmapListener.onSaveBitmapOk(isFinish);
                }
            }
        });

    }


    public void showOrHideTextMapInfo(boolean selected) {
        isShow = selected;
    }
}
